#ifndef __DYNCLASS__
#define __DYNCLASS__

#include <string>
#include <string.h>

#ifndef DLL_API
#define DLL_API __attribute__((visibility("default")))
#endif

typedef void *(*CreatePluginFunc)();
typedef bool (*IsPluginClassFunc)(const char *, int);
struct Plugin {
    const char *mPluginName;
    const char *mPluginVersion;
    CreatePluginFunc mCreateFunc;
    IsPluginClassFunc mIsPluginClass;
};

#define PLUGIN(classType, pluginName, pluginVersion) \
    bool IsPluginClass(const char *baseClass, int size) \
    { \
        if (strlen(baseClass) == strlen("Test") \
            && memcmp("Test", baseClass, strlen(baseClass)) == 0) { \
            return std::is_base_of<Test, classType>::value && sizeof(Test) == size; \
        } \
        return false; \
    } \
    extern "C" { \
    void *CreatePlugin() \
    { \
        return new classType(); \
    } \
    DLL_API Plugin exports = \
        { \
            pluginName, \
            pluginVersion, \
            CreatePlugin, \
            IsPluginClass, \
    }; \
    }

class Test
{
public:
    virtual ~Test() { }
    virtual int function_add(int a, int b) = 0;
    virtual std::string version() = 0;
};

#endif // __DYNCLASS__
